package com.waitingresult.thread;


import java.util.concurrent.locks.ReentrantLock;

/**
 * All right reserved,Designed By WangShuai
 *
 * @author : WangShuai
 * @version : V1.0
 * @ClassName : RedObjectMemoryLayoutDemo
 * @Description : 读取Java对象的内存布局
 * @date : 2022/9/18 11:38
 */
public class RedObjectMemoryLayoutDemo {
    public static void main(String[] args) {
        /**
         * 问 一个对象 在JVM虚拟机中 占用多少个字节？
         */
        ReentrantLock lock = new ReentrantLock();
//        lock.lock();
//        Object o = new Object();
//        System.err.println(ClassLayout.parseInstance(o).toPrintable());
        /*
         打印结果
        //JOL-version 9 Print
        MarkWord ： 对象头 占用 8个字节
        ClassPointer： 经过压缩之后 占用 4个字节
        InstanceData ： 由于是空的Object对象 所以占用4个字节
        padding : 由于对象总共占用的字节数不能被8整除，所以要进行内存补齐。 此时 Object o = new Object(); 占用了16个字节

        OFF  SZ   TYPE DESCRIPTION               VALUE
        // 从0个字节开始到后面的8个字节， 这段数据 是这个对象的头信息的标识
        // 对象头
        0     4        (object header)                                01 00 00 00 (00000001 00000000 00000000 00000000) (1)
        // 对象实例数据
        4     4        (object header)                                00 00 00 00 (00000000 00000000 00000000 00000000) (0)
        //对象实例填充 从8个字节开始到后面的4个字节， 这段数据 是这个class对象的数据信息 也就是说 你对象里面的属性值 方法等 所占的字节都是在这个区域
        8     4        (object header)                                e5 01 00 f8 (11100101 00000001 00000000 11111000) (-134217243)
        12   4        (object alignment gap)    // 对齐间隙 什么意思呢？ 是说 当前这个对象 并没有满16个字节，需要对这个对象进行自动补齐
        Instance size: 16 bytes  // 说当前对象的字节大小占用了16个
        //空间损失汇总
        //空间损失：内部 0 字节 + 外部 4 字节 = 总共 4 字节
        //那什么又是空间损失？ 就是自动补齐的这部分字节空间。它是在内存中占用大小的，却又没有数据 但JVM又要求一个对象占用的字节必须是8的倍数， 自动补齐的意思就是没有内容的时候去补0
        //那为什么需要内存补齐？ CPU在读内存值的时候，是根据IO总线的宽度来读，如果这个值的大小可以被8整除 它读起来就会特别快，是用来提升效率的
        Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

        当CMD敲Java命令的时候 它默认带的参数
        -XX:InitialHeapSIze = 133 //起始堆大小
        -XX:MaxHeapSIze = 133 //最大堆大小
        -XX:+UseCompressedClassPointers // 使用压缩类指针
        -XX:+UseCompressedOops  // 使用压缩的 Oop 普通对象指针，默认也是压缩的4个字节
        Java是一个64位的系统来说，JVM是64位的， 指针的长度也应该是64位 也就是8个字节，
            由于JVM 开启了 压缩指针 它会把默认的8个字节压缩成4个字节来节省内存
            也就是默认 指针就是4个字节





















         */
    }
}
